多模态 LLM
纯文本模型处理不了图表、照片、音视频。多模态 LLM 要做的是把别的模态接进同一个自回归框架,而这个「接」的方式有一个出人意料的简单答案:把它变成 token。
通用架构:三件套
绝大多数视觉-语言模型(VLM)是同一个骨架:
图像 → Vision Encoder → Projector → ┐
├→ LLM Backbone → 文本输出
文本 Prompt ─────────────────────────┘| 组件 | 作用 | 常见选择 |
|---|---|---|
| Vision Encoder | 把图像编码成一组向量(视觉 token) | CLIP ViT、SigLIP |
| Projector | 把视觉 token 映射进 LLM 的嵌入空间 | 线性层,或 2 层 MLP |
| LLM Backbone | 接收文本 token 与视觉 token 的混合序列,自回归输出 | LLaMA / Vicuna / Qwen |
这个架构最值得记的一点是:对 LLM 来说视觉 token 和文本 token 没有本质区别 —— 它们是同一个嵌入空间里的向量,注意力同等对待。模型要学的只是「怎么把视觉信息编码成 LLM 能用的 token」。这也是为什么接一个视觉塔只需要训练一个轻量投影层(下一节的 LLaVA),而不是重训整个模型。
Vision Encoder:CLIP 的对比学习
CLIP(OpenAI, 2021)是这一层的事实标准,训练方式是图文对比学习:一批(图像, 文本)对里,配对的图文嵌入距离拉近,不配对的推远。
其中
训练规模是 4 亿对(图像, 文本)。图像侧用的是 ViT:把图切成 14×14 或 16×16 像素的 patch,每个 patch 出一个视觉 token。
patch 尺寸直接决定 token 数:224×224 的输入,按 14 像素切是
CLIP 的对比学习作用在一个 batch 内的相似度矩阵上。
一个 batch 有 N 个(图像, 文本)对,算完整相似度矩阵 (N × N)
文本 t1 文本 t2 文本 t3 … 文本 tN
图像 v1 ┌ sim₁₁ sim₁₂ sim₁₃ sim₁N ┐
图像 v2 │ sim₂₁ sim₂₂ sim₂₃ sim₂N │
图像 v3 │ sim₃₁ sim₃₂ sim₃₃ sim₃N │
… │ … … … … │
图像 vN └ simN₁ simN₂ simN₃ simNN ┘
└─ 对角线:配对样本,要拉近
└─ 非对角线:不配对,要推远
损失函数的分母遍历 batch 内所有文本
ℒ = −(1/N) Σᵢ log[ exp(sim(vᵢ, tᵢ)/τ) / Σⱼ exp(sim(vᵢ, tⱼ)/τ) ]
└─ batch 越大,负样本越多,
对比信号越强
这就是 CLIP 把 batch 做到 32K 的原因。
训练规模 4 亿对图文。图像侧 ViT 把图切成 14×14 或 16×16 像素的 patch,
每个 patch 出一个视觉 token —— 224×224 输入按 14 像素切是 16×16 = 256 个
视觉 token(外加一个 CLS token)。LLaVA:对齐而非重训
LLaVA(Liu et al., 2023)证明了接一个视觉能力不需要大动干戈:
| 组件 | 配置 | 是否训练 |
|---|---|---|
| Vision Encoder | CLIP ViT-L/14 | 冻结 |
| Projector | 2 层 MLP | 训练 |
| LLM | Vicuna(LLaMA 微调版) | 阶段 2 训练 |
两阶段训练:
| 阶段 | 数据 | 训什么 | 目标 |
|---|---|---|---|
| 一:视觉-语言对齐 | 595K 图文对 | 只训 Projector | 学会把视觉 token 映射到 LLM 空间 |
| 二:端到端指令微调 | 150K 多模态指令 | Projector + LLM(或只训 LoRA) | 学会按图像 + 指令作答 |
阶段一冻结两端、只训中间的桥,这个安排是 LLaVA 简洁性的来源 —— 视觉塔和语言模型已有的能力都直接复用,模型只需要学「翻译」。这与参数高效微调是同一个思路的两种形态(16-参数高效微调:LoRA、QLoRA 与 Adapter)。
分辨率与视觉 Token 预算
问题
固定 224×224 输入意味着强制缩放:一张 4000×3000 的手机照片压到 224×224,小字、远处人脸、表格里的数字全部丢失。
动态分辨率
做法是把高分辨率图切成多个 tile,每个 tile 独立编码,再加一张缩略图提供全局信息(LLaVA-1.6 的 AnyRes 走这条路)。
按 224×224 一块的切法算:
| 输入 | tile 数 | 视觉 token |
|---|---|---|
| 224×224 | 1 | 256 |
| 448×448 | 4 | 1024 |
| 896×896 | 16 | 4096 |
token 数随面积平方增长,而上下文窗口是有限的 —— 一张 896×896 的图吃掉 4096 个 token,留给文本对话的空间被大幅挤压。
动态分辨率把高分辨率图切成多个 tile,各自独立编码。
固定 224×224:整张图被强制缩放
4000×3000 的手机照片 ──▶ 压到 224×224 ──▶ 小字、远处人脸、表格里的数字全部丢失
动态分辨率(以 224×224 为一块,896×896 的输入为例)
┌────┬────┬────┬────┐ 每块独立过 Vision Encoder,各出 256 个视觉 token
│ ① │ ② │ ③ │ ④ │
├────┼────┼────┼────┤
│ ⑤ │ ⑥ │ ⑦ │ ⑧ │ 再加一张缩略图提供全局信息
├────┼────┼────┼────┤ (LLaVA-1.6 的 AnyRes 走这条路)
│ ⑨ │ ⑩ │ ⑪ │ ⑫ │
├────┼────┼────┼────┤
│ ⑬ │ ⑭ │ ⑮ │ ⑯ │
└────┴────┴────┴────┘
└─▶ 16 × 256 = 4096 个视觉 token
token 数随面积增长:224² 一块(256)→ 448² 四块(1024)→ 896² 十六块(4096)
一张 896×896 的图吃掉 4096 个 token,留给文本对话的空间被大幅挤压。
Token 压缩就是在这条线上往回压:用一组固定数量的可学习查询 token
(Perceiver Resampler 如 64 个、Q-Former 如 32 个)通过 Cross-Attention
抽取信息,让输出长度与分辨率解耦 —— 代价是细粒度识别(小字 OCR)会掉。Token 压缩
既然 token 太多,就用更少的 token 表示同一张图:
| 方案 | 做法 | 输出长度 |
|---|---|---|
| Perceiver Resampler(Flamingo) | 一组固定数量的可学习查询 token,通过 Cross-Attention 从视觉 token 里抽取信息 | 固定(如 64 个) |
| Q-Former(BLIP-2) | 结构更复杂的 Querying Transformer,同样是固定查询数 | 固定(如 32 个) |
固定查询数的好处是输出长度与图像分辨率解耦 —— 无论输入多大,视觉 token 数都是常数,显存和上下文占用可预测。代价是信息被压缩进固定容量,细粒度识别(小字 OCR)会掉。
这是一条明确的权衡线:分辨率换细节,压缩换上下文预算。选择取决于任务 —— 文档理解要前者,通用对话可以要后者。
除了「看图」还要「定位」
| 能力 | 说明 |
|---|---|
| Grounding | 把自然语言描述映射到图中的具体区域(Bounding Box) |
| OCR | 文档、路标、表格里的文字 |
| 图表理解 | 从柱状图、折线图里读出数据与趋势 |
| 空间推理 | 「苹果在桌子上」这类物体间关系 |
这几项都需要更高的分辨率与更精细的训练数据,是动态分辨率方案的主要驱动力。
原生多模态 vs 拼接式
| 路线 | 做法 | 代表 |
|---|---|---|
| 拼接式 | 先训好语言模型 + 预训练视觉塔,再用 Projector 接起来 | LLaVA、Qwen-VL |
| 原生多模态 | 从预训练阶段就混合多模态数据,架构本身为多模态设计 | Gemini |
拼接式的优势是可以复用现成的强组件(CLIP + LLaMA),代价是各模态在各自的预训练里形成了不同的统计特性,对齐层要弥合这个鸿沟。原生路线没有这道鸿沟,但要从头训且数据成本高。
一个能说明差别的例子是语音:
| 方案 | 做法 | 代价 |
|---|---|---|
| 流水线 | ASR → 文本 → LLM → TTS | 延迟高(要等 ASR 出全文);丢掉副语言信息(语调、情感、停顿) |
| 端到端 | 音频波形直接编码成 token,与文本一起进 LLM | 无需等待转录,延迟低;能感知语气 |
GPT-4o 的端到端语音是「原生」这条路线的直接价值体现 —— 它的低延迟来自两处:省掉了等待转录的那一环,也保住了流水线里必然丢失的那部分信号(语调、情感、停顿)。
视频:信息量的硬约束
一分钟 30fps 的视频有 1800 帧。每帧按最小配置 256 token 算,全帧输入就是 46 万 token —— 当前的上下文窗口扛不住。
主流做法是关键帧采样:均匀或按内容挑少量帧(如每秒 1–2 帧),逐帧编码后拼成 token 序列。
按每秒 1 帧、每帧 256 token 估算:
| 视频长度 | 帧数 | token |
|---|---|---|
| 1 分钟 | 60 | 15,360 |
| 10 分钟 | 600 | 153,600 |
| 1 小时 | 3600 | 921,600 |
一小时视频约 92 万 token —— 这就是为什么视频理解实际上是在吃长上下文能力(14-长上下文技术),也是「百万级上下文」最早的真实需求场景之一。采样率是这一环最直接的旋钮:降一半就省一半 token,代价是快速动作与短事件被漏掉。
视频的 token 预算由采样率直接决定。
一分钟 30 fps 的视频 = 1800 帧
每帧按最小配置 256 token 算
└─▶ 1800 × 256 = 46 万 token,当前上下文窗口扛不住
改成关键帧采样(每秒 1 帧)
1 分钟 60 帧 15,360 token
10 分钟 600 帧 153,600 token
1 小时 3,600 帧 921,600 token
└─ 一小时视频约 92 万 token
所以视频理解实际上是在吃长上下文能力 ——「百万级上下文」最早的真实需求
场景之一就在这里。
采样率是这一环最直接的旋钮:降一半就省一半 token,
代价是快速动作与短事件被漏掉。模型格局(2024 年快照)
| 模型 | 视觉 | 音频 | 上下文 | 特点 |
|---|---|---|---|---|
| GPT-4V | 图像 | 否 | 128K | 强视觉推理 |
| GPT-4o | 图像 | 音频 | 128K | 端到端多模态、实时语音 |
| Gemini 1.5 Pro | 图像 / 视频 | 音频 | 1M | 原生多模态、超长上下文 |
| Claude 3.5 Sonnet | 图像 | 否 | 200K | 视觉 + 长上下文 |
| LLaVA-1.6 | 图像 | 否 | 32K | 开源标杆 |
| Qwen-VL-2 | 图像 / 视频 | 否 | 32K | 开源,中文优化 |
这张表是时间点快照
模态支持与上下文长度是各家迭代最快的两项参数,引用前要查当期规格。表的价值在于它标出了能力维度的组合方式(哪些模型有音频、哪些支持视频、上下文量级),这些组合的形态比具体数字稳定得多。
相关
- 02-Transformer 架构 —— 自注意力与嵌入空间,视觉 token 能直接复用的前提
- 05-文本分词与子词算法:BPE、WordPiece 与 Unigram —— 文本侧的分词 vs 视觉侧的 patch 切分
- 14-长上下文技术 —— 视频理解实际依赖的能力底座
- 09-位置编码 —— 图像的二维位置信息怎么进模型
- 16-参数高效微调:LoRA、QLoRA 与 Adapter —— LLaVA 阶段一只训 Projector 与 PEFT 是同一种省法
- 08-量化 —— 视觉塔的量化与端侧多模态
参考
- https://arxiv.org/abs/2103.00020
- https://arxiv.org/abs/2304.08485
- https://arxiv.org/abs/2310.03744
- https://arxiv.org/abs/2204.14198
- https://arxiv.org/abs/2301.12597
- https://arxiv.org/abs/2303.15343
- https://arxiv.org/abs/2409.12191 | Gemini 1.5:https://arxiv.org/abs/2403.05530
- ting.is-a.dev. LLM 原理 专栏第 08 篇.
该篇第 1–4 章属长上下文,已拆分到 14-长上下文技术;本文只收第 5–7 章的架构、分辨率与模态三块
YJ